package org.club.common.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import io.lettuce.core.resource.ClientResources;
import io.lettuce.core.resource.DefaultClientResources;
import org.springframework.context.annotation.Primary;
import javax.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Redis配置类
 * 用于配置RedisTemplate，以方便在应用程序中使用Redis进行数据存储和获取
 */
@Configuration
public class RedisConfig {
    private static final Logger logger = LoggerFactory.getLogger(RedisConfig.class);
    private ClientResources clientResources;

    /**
     * 创建RedisTemplate实例
     * 该方法配置了RedisTemplate的连接工厂和序列化方式，使其可以连接到Redis服务器并进行数据操作
     *
     * @param factory Redis连接工厂，用于创建和管理Redis连接
     * @return 配置好的RedisTemplate实例，可用于执行Redis操作
     */
    @Bean
    @Primary // 确保这是主要的RedisTemplate Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new StringRedisSerializer());
        return template;
    }

    /**
     * 配置Lettuce客户端资源，确保在应用关闭时正确关闭EventLoopGroup
     */
    @Bean(destroyMethod = "shutdown")
    public ClientResources clientResources() {
        clientResources = DefaultClientResources.builder()
            .ioThreadPoolSize(4)
            .computationThreadPoolSize(4)
            .build();
        return clientResources;
    }

    /**
     * 自定义Lettuce客户端配置，使用上面定义的ClientResources
     */
    @Bean
    public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(ClientResources clientResources) {
        return builder -> builder.clientResources(clientResources);
    }

    @PreDestroy
    public void destroy() {
        logger.info("正在关闭Redis资源...");
        if (clientResources != null) {
            try {
                clientResources.shutdown();
                logger.info("Redis资源已成功关闭");
            } catch (Exception e) {
                logger.error("关闭Redis资源时发生错误", e);
            }
        }
    }
}
